<template>
    <input type="file" @input="handleFileInput"><br>
    总分片数【{{ zongFPS }}】，消耗时间【{{ xiaohaoTime }}】
    <div class="loading" :class="{ 'showLoading': isLoading }">
        <div class="socket">
            <div class="gel center-gel">
                <div class="hex-brick h1"></div>
                <div class="hex-brick h2"></div>
                <div class="hex-brick h3"></div>
            </div>
            <div v-for="i in 37" :class="'gel c' + i + ' r' + huanshu(i)">
                <div class="hex-brick h1"></div>
                <div class="hex-brick h2"></div>
                <div class="hex-brick h3"></div>
            </div>
        </div>

    </div>
</template>
  
<script>
import { ref } from 'vue';
import spark from 'spark-md5';

export default {
    setup() {
        const isLoading = ref(false);
        const selectedFile = ref(null);
        const CHUNK_SIZE = 1024 * 1024 * 5; // 5MB
        let MAX_CONCURRENT_REQUESTS = 4; // 最大并发请求数量
        const zongFPS = ref(0);
        const xiaohaoTime = ref(0)

        // 检测设备核心数并将最大并发请求数量设置为核心数
        if (navigator.hardwareConcurrency) {
            MAX_CONCURRENT_REQUESTS = navigator.hardwareConcurrency;
        }

        const handleFileInput = async (event) => {
            const file = event.target.files[0];
            selectedFile.value = file;
            isLoading.value = true;
            // 计时
            const startTime = performance.now();
            // 处理文件逻辑
            const chunks = await cutFile(file);
            const endTime = performance.now();
            xiaohaoTime.value = (endTime - startTime) / 1000 + '秒';
            isLoading.value = false;
            console.log(chunks);
        };

        const cutFile = async (file) => {
            // 分片数量向上取整
            const chunks = [];
            const chunkCount = Math.ceil(file.size / CHUNK_SIZE);
            zongFPS.value = chunkCount;

            const promises = [];

            for (let i = 0; i < chunkCount; i++) {
                const promise = createChunk(file, i, chunkCount);
                promises.push(promise);

                if (promises.length === MAX_CONCURRENT_REQUESTS || i === chunkCount - 1) {
                    const resolvedChunks = await Promise.all(promises);
                    chunks.push(...resolvedChunks);
                    promises.length = 0; // 清空 promise 数组
                }
            }
            return chunks;
        };

        const createChunk = async (file, index, total) => {
            return new Promise((resolve, reject) => {
                // 文件开始位置
                const start = index * CHUNK_SIZE;

                // 文件结束位置
                const end = Math.min(start + CHUNK_SIZE, file.size);

                // 哈希值
                const hash = new spark.ArrayBuffer();

                // 创建文件读取器
                const reader = new FileReader();

                // 读取文件
                const blob = file.slice(start, end);

                // 监听文件读取完成
                reader.onload = (e) => {
                    const chunk = e.target.result;
                    hash.append(chunk);
                    const hexHash = hash.end();
                    resolve({
                        start,
                        end,
                        index,
                        hash: hexHash,
                        blob,
                    });
                };

                reader.onerror = (e) => {
                    reject(e.target.error);
                };

                reader.readAsArrayBuffer(blob);
            });
        };
        const huanshu = (i) => {
            if (i < 7) {
                return 1
            } else if (i >= 7 && i < 19) {
                return 2
            } else {
                return 3
            }
        }
        return {
            handleFileInput,
            CHUNK_SIZE,
            zongFPS,
            xiaohaoTime,
            isLoading,
            huanshu
        };
    },
};

</script>
  
<style lang="scss" scoped>
.loading {
    height: 100vh;
    width: 100vw;
    background-color: #0006;
    position: fixed;
    opacity: 0;
    top: 0;
    left: 0;
    z-index: -1;
    transition: all 0.3s;
    transition: z-index 0s;
}

.showLoading {
    opacity: 1;
    z-index: 999;

}

.socket {
    width: 200px;
    height: 200px;
    position: absolute;
    left: 50%;
    margin-left: -100px;
    top: 50%;
    margin-top: -100px;
}

.hex-brick {
    background: #000000;
    width: 30px;
    height: 17px;
    position: absolute;
    top: 5px;
    animation-name: fade00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    -webkit-animation-name: fade00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
}

.h2 {
    transform: rotate(60deg);
    -webkit-transform: rotate(60deg);
}

.h3 {
    transform: rotate(-60deg);
    -webkit-transform: rotate(-60deg);
}

.gel {
    height: 30px;
    width: 30px;
    transition: all .3s;
    -webkit-transition: all .3s;
    position: absolute;
    top: 50%;
    left: 50%;
}

.center-gel {
    margin-left: -15px;
    margin-top: -15px;
    animation-name: pulse00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    -webkit-animation-name: pulse00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
}

.c1 {
    margin-left: -47px;
    margin-top: -15px;
}

.c2 {
    margin-left: -31px;
    margin-top: -43px;
}

.c3 {
    margin-left: 1px;
    margin-top: -43px;
}

.c4 {
    margin-left: 17px;
    margin-top: -15px;
}

.c5 {
    margin-left: -31px;
    margin-top: 13px;
}

.c6 {
    margin-left: 1px;
    margin-top: 13px;
}

.c7 {
    margin-left: -63px;
    margin-top: -43px;
}

.c8 {
    margin-left: 33px;
    margin-top: -43px;
}

.c9 {
    margin-left: -15px;
    margin-top: 41px;
}

.c10 {
    margin-left: -63px;
    margin-top: 13px;
}

.c11 {
    margin-left: 33px;
    margin-top: 13px;
}

.c12 {
    margin-left: -15px;
    margin-top: -71px;
}

.c13 {
    margin-left: -47px;
    margin-top: -71px;
}

.c14 {
    margin-left: 17px;
    margin-top: -71px;
}

.c15 {
    margin-left: -47px;
    margin-top: 41px;
}

.c16 {
    margin-left: 17px;
    margin-top: 41px;
}

.c17 {
    margin-left: -79px;
    margin-top: -15px;
}

.c18 {
    margin-left: 49px;
    margin-top: -15px;
}

.c19 {
    margin-left: -63px;
    margin-top: -99px;
}

.c20 {
    margin-left: 33px;
    margin-top: -99px;
}

.c21 {
    margin-left: 1px;
    margin-top: -99px;
}

.c22 {
    margin-left: -31px;
    margin-top: -99px;
}

.c23 {
    margin-left: -63px;
    margin-top: 69px;
}

.c24 {
    margin-left: 33px;
    margin-top: 69px;
}

.c25 {
    margin-left: 1px;
    margin-top: 69px;
}

.c26 {
    margin-left: -31px;
    margin-top: 69px;
}

.c27 {
    margin-left: -79px;
    margin-top: -15px;
}

.c28 {
    margin-left: -95px;
    margin-top: -43px;
}

.c29 {
    margin-left: -95px;
    margin-top: 13px;
}

.c30 {
    margin-left: 49px;
    margin-top: 41px;
}

.c31 {
    margin-left: -79px;
    margin-top: -71px;
}

.c32 {
    margin-left: -111px;
    margin-top: -15px;
}

.c33 {
    margin-left: 65px;
    margin-top: -43px;
}

.c34 {
    margin-left: 65px;
    margin-top: 13px;
}

.c35 {
    margin-left: -79px;
    margin-top: 41px;
}

.c36 {
    margin-left: 49px;
    margin-top: -71px;
}

.c37 {
    margin-left: 81px;
    margin-top: -15px;
}

.r1 {
    animation-name: pulse00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-delay: .2s;
    -webkit-animation-name: pulse00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-delay: .2s;
}

.r2 {
    animation-name: pulse00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-delay: .4s;
    -webkit-animation-name: pulse00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-delay: .4s;
}

.r3 {
    animation-name: pulse00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-delay: .6s;
    -webkit-animation-name: pulse00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-delay: .6s;
}

.r1>.hex-brick {
    animation-name: fade00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-delay: .2s;
    -webkit-animation-name: fade00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-delay: .2s;
}

.r2>.hex-brick {
    animation-name: fade00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-delay: .4s;
    -webkit-animation-name: fade00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-delay: .4s;
}

.r3>.hex-brick {
    animation-name: fade00;
    animation-duration: 2s;
    animation-iteration-count: infinite;
    animation-delay: .6s;
    -webkit-animation-name: fade00;
    -webkit-animation-duration: 2s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-delay: .6s;
}

@keyframes pulse00 {
    0% {
        -webkit-transform: scale(1);
        transform: scale(1);
    }

    50% {
        -webkit-transform: scale(0.01);
        transform: scale(0.01);
    }

    100% {
        -webkit-transform: scale(1);
        transform: scale(1);
    }
}

@keyframes fade00 {
    0% {
        background: #252525;
    }

    50% {
        background: #000000;
    }

    100% {
        background: #353535;
    }
}
</style>